/**
 * Copyright (c) <2010>, <SUNNY GUPTA>
 * All rights reserved.

 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of the <ORGANIZATION> nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <SUNNY GUPTA> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.gwtp.investmentadvisor.client.di;

import com.google.inject.Singleton;
import com.gwtplatform.dispatch.client.DefaultExceptionHandler;
import com.gwtplatform.dispatch.client.DefaultSecurityCookieAccessor;
import com.gwtplatform.dispatch.client.gin.DispatchAsyncModule;
import com.gwtplatform.mvp.client.DefaultEventBus;
import com.gwtplatform.mvp.client.DefaultProxyFailureHandler;
import com.gwtplatform.mvp.client.EventBus;
import com.gwtplatform.mvp.client.RootPresenter;
import com.gwtplatform.mvp.client.gin.AbstractPresenterModule;
import com.gwtplatform.mvp.client.proxy.ParameterTokenFormatter;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.ProxyFailureHandler;
import com.gwtplatform.mvp.client.proxy.TokenFormatter;
import com.gwtp.investmentadvisor.client.common.AppCache;
import com.gwtp.investmentadvisor.client.common.AppCacheImpl;
import com.gwtp.investmentadvisor.client.dispatch.actionhandler.AppClientActionHandlerRegistry;
import com.gwtp.investmentadvisor.client.dispatch.actionhandler.FinancialSecuritySearchActionHandler;
import com.gwtp.investmentadvisor.client.gatekeeper.LoggedInGateKeeper;
import com.gwtp.investmentadvisor.client.gatekeeper.NotLoggedInGateKeeper;
import com.gwtp.investmentadvisor.client.gui.authentication.LoginScreenPresenter;
import com.gwtp.investmentadvisor.client.gui.authentication.LoginScreenView;
import com.gwtp.investmentadvisor.client.gui.authentication.LogoutScreenPresenter;
import com.gwtp.investmentadvisor.client.gui.authentication.LogoutScreenView;
import com.gwtp.investmentadvisor.client.gui.authentication.SignUpScreenPresenter;
import com.gwtp.investmentadvisor.client.gui.authentication.SignUpScreenView;
import com.gwtp.investmentadvisor.client.gui.errorscreen.ErrorScreenPresenter;
import com.gwtp.investmentadvisor.client.gui.errorscreen.ErrorScreenView;
import com.gwtp.investmentadvisor.client.gui.financialsecuritysearch.FinancialSecuritySearchBoxPresenter;
import com.gwtp.investmentadvisor.client.gui.financialsecuritysearch.FinancialSecuritySearchBoxView;
import com.gwtp.investmentadvisor.client.gui.userdashboard.UserDashboardPresenter;
import com.gwtp.investmentadvisor.client.gui.userdashboard.UserDashboardView;
import com.gwtp.investmentadvisor.client.place.AppPlaceManager;
import com.gwtp.investmentadvisor.client.place.DefaultPlace;
import com.gwtp.investmentadvisor.client.place.ErrorPlace;
import com.gwtp.investmentadvisor.client.place.PlaceNameTokens;
import com.gwtp.investmentadvisor.shared.entities.CurrentUser;

/**
 * @author Sunny Gupta
 *
 */
public class InvestmentAdvisorClientModule extends AbstractPresenterModule {

  /* (non-Javadoc)
   * @see com.google.gwt.inject.client.AbstractGinModule#configure()
   */
  @Override
  protected void configure() {
    // Bind EventBus
    bind(EventBus.class).to(DefaultEventBus.class).in(Singleton.class);
    
    // Bind Place Management Stuff
    bind(TokenFormatter.class).to(ParameterTokenFormatter.class).in(Singleton.class);
    bind(PlaceManager.class).to(AppPlaceManager.class).in(Singleton.class);
    bind(ProxyFailureHandler.class).to(DefaultProxyFailureHandler.class).in(Singleton.class);
    
    // Bind dispatch service in custom manner
    // TODO: Might need change for security
    install(new DispatchAsyncModule(DefaultExceptionHandler.class, 
        DefaultSecurityCookieAccessor.class,
        AppClientActionHandlerRegistry.class));
    
    // Client Action Handlers
    bind(FinancialSecuritySearchActionHandler.class).in(Singleton.class);

    // Bind Current User as eager singleton as we need it to be created before any place request
    bind(CurrentUser.class).asEagerSingleton();
      
    // Cache for the application
    bind(AppCache.class).to(AppCacheImpl.class).in(Singleton.class);

    // Bind Constants    
    bindConstant().annotatedWith(DefaultPlace.class).to(
        PlaceNameTokens.LoginScreenNameToken);
    bindConstant().annotatedWith(ErrorPlace.class).to(
        PlaceNameTokens.ErrorScreenNameToken);
    
    // Bind Gatekeepers
    bind(LoggedInGateKeeper.class).in(Singleton.class);
    bind(NotLoggedInGateKeeper.class).in(Singleton.class);
    
    // Bind Presenters (and their views)
    
    // Root Presenter
    bind(RootPresenter.class).asEagerSingleton();
    
    // FinancialSecuritySearchBox
    bindPresenter(FinancialSecuritySearchBoxPresenter.class,
        FinancialSecuritySearchBoxPresenter.Display.class, 
        FinancialSecuritySearchBoxView.class, FinancialSecuritySearchBoxPresenter.Proxy.class);
    // LoginScreen
    bindPresenter(LoginScreenPresenter.class, LoginScreenPresenter.Display.class, 
        LoginScreenView.class, LoginScreenPresenter.Proxy.class);
    // SignUpScreen
    bindPresenter(SignUpScreenPresenter.class, SignUpScreenPresenter.Display.class, 
        SignUpScreenView.class, SignUpScreenPresenter.Proxy.class);
    // UserDashboard
    bindPresenter(UserDashboardPresenter.class, UserDashboardPresenter.Display.class,
        UserDashboardView.class, UserDashboardPresenter.Proxy.class);
    // ErrorScreen
    bindPresenter(ErrorScreenPresenter.class, ErrorScreenPresenter.Display.class,
        ErrorScreenView.class, ErrorScreenPresenter.Proxy.class);
    // LogoutScreen
    bindPresenter(LogoutScreenPresenter.class, LogoutScreenPresenter.Display.class,
        LogoutScreenView.class, LogoutScreenPresenter.Proxy.class);
  }
  
}
